﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace ExchangeListener
{
    class AppointmentsListener
    {
        private AppointmentsListener()
        {
        }

        private static AppointmentsListener ga;

        public static AppointmentsListener Instance
        {
            get
            {
                if (ga == null)
                    ga = new AppointmentsListener();
                return ga;
            }
        }


        private Hashtable list;

        public void Listener(DateTime StartTime, DateTime EndTime, ExchangeServiceBinding esb, Hashtable _list)
        {
            list = _list;
            GetAppointments(StartTime, EndTime, esb);
        }

        private AndType GetAT(DateTime StartTime, DateTime EndTime)
        {
            PathToUnindexedFieldType StartDateReceivedField = new PathToUnindexedFieldType();
            StartDateReceivedField.FieldURI = UnindexedFieldURIType.calendarStart;
            ConstantValueType StartDateReceivedToGet = new ConstantValueType();
            StartDateReceivedToGet.Value = StartTime.ToUniversalTime().ToString();
            FieldURIOrConstantType StartDateReceivedConstant = new FieldURIOrConstantType();
            StartDateReceivedConstant.Item = StartDateReceivedToGet;
            IsGreaterThanOrEqualToType igtett = new IsGreaterThanOrEqualToType();
            igtett.FieldURIOrConstant = StartDateReceivedConstant;
            igtett.Item = StartDateReceivedField;


            //restrict the returned items less than a specified date
            PathToUnindexedFieldType EndDateReceivedField = new PathToUnindexedFieldType();
            EndDateReceivedField.FieldURI = UnindexedFieldURIType.calendarEnd;
            ConstantValueType EndDateReceivedToGet = new ConstantValueType();
            EndDateReceivedToGet.Value = EndTime.ToUniversalTime().ToString();
            FieldURIOrConstantType EndDateReceivedConstant = new FieldURIOrConstantType();
            EndDateReceivedConstant.Item = EndDateReceivedToGet;
            IsLessThanOrEqualToType iltett = new IsLessThanOrEqualToType();
            iltett.FieldURIOrConstant = EndDateReceivedConstant;
            iltett.Item = EndDateReceivedField;

            PathToUnindexedFieldType MsgClassField = new PathToUnindexedFieldType();
            MsgClassField.FieldURI = UnindexedFieldURIType.calendarIsRecurring;
            ConstantValueType MsgClassToGet = new ConstantValueType();
            MsgClassToGet.Value = "0";
            FieldURIOrConstantType MsgClassConstant = new FieldURIOrConstantType();
            MsgClassConstant.Item = MsgClassToGet;
            IsEqualToType iett = new IsEqualToType();
            iett.FieldURIOrConstant = MsgClassConstant;
            iett.Item = MsgClassField;

            AndType at = new AndType();
            at.Items = new SearchExpressionType[3];
            at.Items[0] = igtett;
            at.Items[1] = iltett;
            at.Items[2] = iett;

            return at;
        }

        private void GetAppointments(DateTime StartTime, DateTime EndTime, ExchangeServiceBinding esb)
        {
            var response = esb.FindItem(new FindItemType
            {
                ItemShape = new ItemResponseShapeType
                {
                    BaseShape = DefaultShapeNamesType.AllProperties,
                    AdditionalProperties = new PathToUnindexedFieldType[] { 
                        new PathToUnindexedFieldType{
                        FieldURI=UnindexedFieldURIType.calendarIsMeeting
                        }
                    }
                },
                ParentFolderIds = new DistinguishedFolderIdType[] 
                        { 
                            new DistinguishedFolderIdType { Id = DistinguishedFolderIdNameType.calendar }, 
                        },

                Restriction = new RestrictionType { Item = GetAT(StartTime, EndTime) }
            });

            var items = ((ArrayOfRealItemsType)((FindItemResponseMessageType)response.ResponseMessages.Items[0]).RootFolder.Item).Items;

            if (items != null)
                foreach (CalendarItemType ci in items)
                {
                    if (ci.ReminderIsSet)
                    {
                        if (!list.ContainsKey(ci.ItemId.Id))
                        {
                            Appointment ap = new Appointment();
                            ap.ID = ci.ItemId.Id;
                            ap.Subject = ci.Subject;
                            ap.Location = ci.Location;
                            ap.Start = ci.Start.ToLocalTime();
                            ap.ReminderMinutesBeforeStart = Convert.ToInt32(ci.ReminderMinutesBeforeStart);
                            //ap.RemindTime = ci.Start.AddMinutes(-Convert.ToDouble(ci.ReminderMinutesBeforeStart)).ToLocalTime();
                            ap.IsNotified = false;
                            list.Add(ci.ItemId.Id, ap);
                        }
                    }
                }
        }


    }
}
